#include "U2DepthBuffer.h"

#include "U2RenderTarget.h"


U2EG_NAMESPACE_USING


U2DepthBuffer::U2DepthBuffer( u2uint16 poolId, u2uint16 bitDepth, u2uint32 width, u2uint32 height,
						  u2uint32 fsaa, const U2String &fsaaHint, bool manual )
: mPoolId(poolId)
, mBitDepth(bitDepth)
, mWidth(width)
, mHeight(height)
, mFsaa(fsaa)
, mFsaaHint(fsaaHint)
, mManual(manual)
{
}

U2DepthBuffer::~U2DepthBuffer()
{
	detachFromAllRenderTargets();
}

void U2DepthBuffer::_setPoolId( u2uint16 poolId )
{
	//Change the pool Id
	mPoolId = poolId;

	//Render Targets were attached to us, but they have a different pool Id,
	//so detach ourselves from them
	detachFromAllRenderTargets();
}
//-----------------------------------------------------------------------
u2uint16 U2DepthBuffer::getPoolId() const
{
	return mPoolId;
}
//-----------------------------------------------------------------------
u2uint16 U2DepthBuffer::getBitDepth() const
{
	return mBitDepth;
}
//-----------------------------------------------------------------------
u2uint32 U2DepthBuffer::getWidth() const
{
	return mWidth;
}
//----------------------------------------------------------------------
u2uint32 U2DepthBuffer::getHeight() const
{
	return mHeight;
}
//-----------------------------------------------------------------------
u2uint32 U2DepthBuffer::getFsaa() const
{
	return mFsaa;
}
//-----------------------------------------------------------------------
const U2String& U2DepthBuffer::getFsaaHint() const
{
	return mFsaaHint;
}
//-----------------------------------------------------------------------
bool U2DepthBuffer::isManual() const
{
	return mManual;
}
//-----------------------------------------------------------------------
bool U2DepthBuffer::isCompatible( U2RenderTarget *renderTarget ) const
{
	if( this->getWidth() >= renderTarget->getWidth() &&
		this->getHeight() >= renderTarget->getHeight() &&
		this->getFsaa() == renderTarget->getFSAA() )
	{
		return true;
	}

	return false;
}
//-----------------------------------------------------------------------
void U2DepthBuffer::_notifyRenderTargetAttached( U2RenderTarget *renderTarget )
{
	assert( mAttachedRenderTargets.find( renderTarget ) == mAttachedRenderTargets.end() );

	mAttachedRenderTargets.insert( renderTarget );
}
//-----------------------------------------------------------------------
void U2DepthBuffer::_notifyRenderTargetDetached( U2RenderTarget *renderTarget )
{
	RenderTargetSet::iterator itor = mAttachedRenderTargets.find( renderTarget );
	assert( itor != mAttachedRenderTargets.end() );

	mAttachedRenderTargets.erase( itor );
}
//-----------------------------------------------------------------------
void U2DepthBuffer::detachFromAllRenderTargets()
{
	RenderTargetSet::const_iterator itor = mAttachedRenderTargets.begin();
	RenderTargetSet::const_iterator end  = mAttachedRenderTargets.end();
	while( itor != end )
	{
		//If we call, detachDepthBuffer, we'll invalidate the iterators
		(*itor)->_detachDepthBuffer();
		++itor;
	}

	mAttachedRenderTargets.clear();
}
